#include "comm.h"

/* Functions for massage queue */
static int commMsgQueue(int flags)
{
    key_t key = ftok("/tmp",1);
    if(key < 0)
    {
        perror("ftok");
        return -1;
    }
    int msg_id = msgget(key, flags);
    if(msg_id < 0)
    {
        perror("msgget");
        return -1;
    }
    return msg_id;
}

int createMsgQueue()
{
    return commMsgQueue(IPC_CREAT | IPC_EXCL | 0666);
}

int getMsgQueue()
{
    return commMsgQueue(IPC_CREAT);
}

int destoryMsgQueue(int msg_id)
{
    if(msgctl(msg_id, IPC_RMID, NULL) < 0)
    {
        perror("msgctl");
        return -1;
    }
}

int sendMsgQueue(int msg_id, char* msg)
{
    struct msgbuf buf;
    strcpy(buf.msgtext, msg);
    buf.msgtype = 1;
    
    if(msgsnd(msg_id, &buf, sizeof(buf.msgtext), 0) < 0)
    {
        perror("msgsnd");
        return -1;
    }
    return 0;
}

int recvMsgQueue(int msg_id, char out[])
{
    struct msgbuf buf;
    buf.msgtype = 0;
    int size = sizeof(buf.msgtext);
    if(msgrcv(msg_id, &buf, size, (long int)0, 0) < 0)
    {
        perror("msgrcv");
        return -1;
    }

    strncpy(out, buf.msgtext, size);
    out[size] = 0;
    return 0;
}

/* Functions for named pipes */
int createFIFOPipe()
{
    if(access(FIFO_PATH, F_OK) != -1) // make sure fifo file not exist before
        removeFIFOPipe();             // create it.
    if(mkfifo(FIFO_PATH, 0666) < 0)
    {
        perror("mkfifo");
        return -1;
    }
    return 0;
}

int removeFIFOPipe()
{
    if(unlink(FIFO_PATH) < 0)
    {
        perror("unlink");
        return -1;
    }
    return 0;
}

int readFIFOPipe(char output[], int size)
{
    int fd = 0;
    int length = 0;

    fd = open(FIFO_PATH, O_RDONLY);
    if(fd < 0)
    {
        perror("ropen");
        return -1;
    }

    length = read(fd, output, size);
    if(length < 0)
    {
        perror("read");
        close(fd);
        return -1;
    }

    output[size] = 0;
    close(fd);

    return 0;
}

int writeFIFOPipe(char input[], int size)
{
    int fd = 0;
    int length = 0;

    fd = open(FIFO_PATH, O_WRONLY);
    if(fd < 0)
    {
        perror("wopen");
        return -1;
    }

    length = write(fd, input, size+1);
    if(length < 0)
    {
        perror("write");
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
}
